package com.backend.modules.task.controller;

import com.backend.common.model.R;
import com.backend.modules.task.convert.TaskConvert;
import com.backend.modules.task.dto.TaskDTO;
import com.backend.modules.task.dto.TaskQueryDTO;
import com.backend.modules.task.service.TaskService;
import com.backend.modules.task.vo.TaskSubmissionDetailVO;
import com.backend.modules.task.vo.TaskVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 任务管理接口
 * 提供任务的CRUD操作
 * 只有教师角色可以访问这些接口
 */
@Tag(name = "任务管理", description = "任务管理相关接口")
@RestController
@RequestMapping("/v1/tasks")
@RequiredArgsConstructor
@PreAuthorize("hasRole('TEACHER')")
public class TaskController {

    private final TaskService taskService;

    /**
     * 创建新任务
     * @param dto 任务参数
     * @return 操作结果
     */
    @Operation(summary = "创建任务")
    @PostMapping
    public R<Void> create(@Validated @RequestBody TaskDTO dto) {
        taskService.create(dto);
        return R.ok();
    }

    /**
     * 更新任务信息
     * @param id 任务ID
     * @param dto 任务参数
     * @return 操作结果
     */
    @Operation(summary = "更新任务")
    @PutMapping("/{id}")
    public R<Void> update(@PathVariable Long id, @Validated @RequestBody TaskDTO dto) {
        taskService.update(id, dto);
        return R.ok();
    }

    /**
     * 删除任务
     * @param id 任务ID
     * @return 操作结果
     */
    @Operation(summary = "删除任务")
    @DeleteMapping("/{id}")
    public R<Void> delete(@PathVariable Long id) {
        taskService.delete(id);
        return R.ok();
    }

    /**
     * 获取任务详情
     * @param id 任务ID
     * @return 任务详情，包含提交统计信息
     */
    @Operation(summary = "获取任务详情")
    @GetMapping("/{id}")
    public R<TaskVO> getById(@PathVariable Long id) {
        TaskVO vo = TaskConvert.convert(taskService.getById(id));
        vo.setStatistics(taskService.getStatistics(id));
        return R.ok(vo);
    }

    /**
     * 分页查询任务列表
     * @param name 任务名称(可选)
     * @param classIds 班级ID列表(可选)
     * @param startTime 开始时间(可选)
     * @param endTime 结束时间(可选)
     * @param pageable 分页参数
     * @return 任务列表，每个任务包含提交统计信息
     */
    @Operation(summary = "分页查询任务")
    @GetMapping("/page")
    public R<Page<TaskVO>> page(
            @Parameter(description = "任务名称") @RequestParam(required = false) String name,
            @Parameter(description = "任务状态") @RequestParam(required = false) String taskStatus,
            @Parameter(description = "班级ID列表") @RequestParam(required = false) List<Long> classIds,
            @Parameter(description = "开始时间") 
            @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") 
            @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @ParameterObject Pageable pageable) {
        
        TaskQueryDTO query = new TaskQueryDTO();
        query.setName(name);
        query.setClassIds(classIds);
        query.setStartTime(startTime);
        query.setEndTime(endTime);
        query.setTaskStatus(taskStatus);
        
        return R.ok(taskService.page(query, pageable).map(task -> {
            TaskVO vo = TaskConvert.convert(task);
            vo.setStatistics(taskService.getStatistics(task.getId()));
            return vo;
        }));
    }

    @Operation(summary = "获取任务提交列表")
    @GetMapping("/{taskId}/submissions")
    public R<Page<TaskSubmissionDetailVO>> getSubmissions(
            @PathVariable Long taskId,
            @Parameter(description = "学生姓名") @RequestParam(required = false) String studentName,
            @Parameter(description = "是否逾期") @RequestParam(required = false) Boolean isLate,
            @ParameterObject Pageable pageable) {
        return R.ok(taskService.getSubmissions(taskId, studentName, isLate, pageable));
    }

    @Operation(summary = "导出提交记录")
    @GetMapping("/{taskId}/submissions/export")
    public void exportSubmissions(
            @PathVariable Long taskId,
            HttpServletResponse response) throws IOException {
        taskService.exportSubmissions(taskId, response);
    }

    @Operation(summary = "批量删除任务")
    @DeleteMapping("/batch")
    public R<Void> batchDelete(@RequestBody List<Long> ids) {
        taskService.batchDelete(ids);
        return R.ok();
    }

    @Operation(summary = "导出已提交文件列表")
    @GetMapping("/{taskId}/submissions/files/export")
    public void exportSubmittedFiles(
            @PathVariable Long taskId,
            HttpServletResponse response) throws IOException {
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=task-" + taskId + "-files.zip");
        taskService.exportSubmittedFilesAsZip(taskId, response.getOutputStream());
    }

    @Operation(summary = "导出未提交学生名单")
    @GetMapping("/{taskId}/submissions/unsubmitted/export")
    public ResponseEntity<byte[]> exportUnsubmittedStudents(@PathVariable Long taskId) {
        return taskService.exportUnsubmittedStudents(taskId);
    }
} 